import BN from 'bn.js';
import Big from 'big.js';
/**
 * 安全除法函数，将两个数值字符串表示的数进行大数除法
 * @param value - 被除数
 * @param divisor - 除数
 * @returns {BN} - 结果
 */
export function safeDivide(value: string, divisor: string): BN {
  const bnValue = new BN(value);
  const bnDivisor = new BN(divisor);
  return bnValue.div(bnDivisor);
}


//精度扩展
export function preciseToInteger(value: string, decimals: number): BN {
  // 将字符串转换为高精度数字
  const bigValue = new Big(value);

  // 计算放大的倍数
  const multiplier = new Big(10).pow(decimals);

  // 将高精度数字放大并转换为字符串形式
  const scaledValue = bigValue.times(multiplier).toFixed();

  // 转换为 BN 对象并返回
  return new BN(scaledValue);
}
// 安全除法函数，还原高精度小数
// export function restoreOriginalValue(scaledValue: BN, decimals: number): string {
//   // 计算放大的倍数
//   const divisor = new BN(10).pow(new BN(decimals));

//   // 执行大整数除法，获取整数部分
//   const quotient = scaledValue.div(divisor);
//   const remainder = scaledValue.mod(divisor);

//   // 还原小数部分
//   const decimalStr = remainder.toString().padStart(decimals, '0');

//   // 组合整数部分和小数部分
//   return `${quotient.toString()}.${decimalStr}`;
// }

// 安全除法函数，还原高精度小数, 移除多余的尾部零
export function restoreOriginalValue(scaledValue: BN, decimals: number): string {
  const divisor = new BN(10).pow(new BN(decimals));
  const quotient = scaledValue.div(divisor);
  const remainder = scaledValue.mod(divisor);
  let decimalStr = remainder.toString().padStart(decimals, '0');

  // 移除小数部分的尾部零
  decimalStr = decimalStr.replace(/0+$/, '');

  // 如果小数部分变为空，直接返回整数部分
  if (decimalStr === '') {
      return quotient.toString();
  }

  return `${quotient.toString()}.${decimalStr}`;
}

// 加法函数
export function preciseAddition(value1: string, value2: string): string {
  const bigValue1 = new Big(value1);
  const bigValue2 = new Big(value2);
  const result = bigValue1.plus(bigValue2);
  return result.toString();
}

// 减法函数
export function preciseSubtraction(value1: string, value2: string): string {
  const bigValue1 = new Big(value1);
  const bigValue2 = new Big(value2);
  const result = bigValue1.minus(bigValue2);
  return result.toString();
}

// 比较函数
export function compareValues(value1: string, value2: string): number {
  const bigValue1 = new Big(value1);
  const bigValue2 = new Big(value2);
  return bigValue1.cmp(bigValue2); // 返回 -1, 0, 或 1
}


// utils.ts
export const fetchNFTImage = async (uri: string): Promise<string> => {
  let nft_img = '';

  try {
      const response = await fetch(uri);
      const contentType = response.headers.get('Content-Type');

      if (contentType && contentType.includes('application/json')) {
          const jsonContent = await response.json();
          nft_img = jsonContent.image;
      } else if (contentType && contentType.includes('image')) {
          nft_img = uri; // 直接使用 URI 作为图片地址
      } else {
          nft_img = '';
      }
  } catch (error) {
      // 捕获错误
      console.error('fetch img error: ', error);
  }

  return nft_img;
};

/**
 * 按照给定的公式计算结果，并返回 BN 对象
 *
 * @param tokenAmount - 字符串表示的 Token 数量（大整数）
 * @param tokenAccRatio - 字符串表示的 Token 比例（小数）
 * @param tokenDebt - 字符串表示的 Token 债务（大整数）
 * @param tokenRemaining - 字符串表示的 Token 剩余数量（大整数）
 * @param nftAmount - 字符串表示的 NFT 数量（大整数）
 * @param nftAccRatio - 字符串表示的 NFT 比例（小数）
 * @param nftRemaining - 字符串表示的 NFT 剩余数量（大整数）
 * @param nftDebt - 字符串表示的 NFT 债务（大整数）
 * @returns 计算结果的 BN 对象
 */
export function calculate(
  tokenAmount: string,
  tokenAccRatio: string,
  tokenDebt: string,
  tokenRemaining: string,
  nftAmount: string,
  nftAccRatio: string,
  nftRemaining: string,
  nftDebt: string
): BN {
  // 使用 Big.js 处理高精度小数和大整数
  const bigTokenAmount = new Big(tokenAmount);
  const bigTokenAccRatio = new Big(tokenAccRatio);
  const bigTokenDebt = new Big(tokenDebt);
  const bigTokenRemaining = new Big(tokenRemaining);
  const bigNftAmount = new Big(nftAmount);
  const bigNftAccRatio = new Big(nftAccRatio);
  const bigNftRemaining = new Big(nftRemaining);
  const bigNftDebt = new Big(nftDebt);

  // 按照公式计算结果
  const result = bigTokenAmount.times(bigTokenAccRatio)
    .minus(bigTokenDebt)
    .plus(bigTokenRemaining)
    .plus(bigNftAmount.times(bigNftAccRatio))
    .plus(bigNftRemaining)
    .minus(bigNftDebt);

  // 将结果转换为字符串形式，并移除小数点，确保转换为 BigInt 再转换为 BN 对象
  const resultStr = result.round().toFixed().replace('.', '');

  // 返回 BN 对象
  return new BN(resultStr);
}
